package admin_admin

import (
	"fmt"
	"gitee.com/theegg/go-brick/app/controller/admin_api"
	"gitee.com/theegg/go-brick/app/controller/partner_api"
	"gitee.com/theegg/go-brick/app/model/admin/admin_permissions"
	"gitee.com/theegg/go-brick/app/model/admin/admin_roles"
	"gitee.com/theegg/go-brick/app/model/partner/partner_admin/partner_admin_menus"
	"gitee.com/theegg/go-brick/app/service/app"
	"gitee.com/theegg/go-brick/app/service/help/cmap"
	"github.com/gin-gonic/gin"
	"strconv"
)

// 获取管理菜单列表
func AdminRoleList(c *gin.Context) {
	params := make(map[string]string)

	// 判定当前登陆用户是否存在
	currentAdminUser, errCurrent := admin_api.GetLoginAdminUser(c)
	if errCurrent != nil {
		app.NewResponse(c).JsonReturn(false, errCurrent.Error(), nil)
		return
	}

	// 获取当前角色
	role, err := currentAdminUser.Role()
	if err != nil || role == nil {
		app.NewResponse(c).JsonReturn(false, "对不起，当前用户角色不存在!", nil)
		return
	}

	// 获取数据
	data, err := role.GetDataList(params, 15)

	if err != nil {
		app.NewResponse(c).JsonReturn(false, "获取数据失败", nil)
		return
	}

	app.NewResponse(c).JsonReturn(true, "获取数据成功", data)
	return
}

// @title AdminRoleEditMenus
// @description 编辑角色菜单
func AdminRoleEditMenus(c *gin.Context) {
	// 1. 获取当前角色
	currentRole, ok := checkAndGetCurrentRole(c)
	if !ok {
		app.NewResponse(c).JsonReturn(false, "对不起, 无效的登陆管理员", nil)
		return
	}

	// 2. 获取当前目标角色
	targetRole, errTar := getAdminRoleFromParams(c)
	if errTar != nil {
		app.NewResponse(c).JsonReturn(false, errTar.Error(), nil)
		return
	}

	// ３. 获取传递的参数 menu ids 并转成map[int64]int64
	checkedMenuStrMapIds := c.PostFormMap("data")
	checkedMenuInt64MapIds, errTrans := cmap.StringMapToInt64Map(checkedMenuStrMapIds)
	if errTrans != nil {
		app.NewResponse(c).JsonReturn(false, errTrans.Error(), nil)
		return
	}

	// 4. 编辑
	ok, errEdit := currentRole.EditRoleMenus(targetRole, checkedMenuInt64MapIds)
	if errEdit != nil {
		app.NewResponse(c).JsonReturn(false, errEdit.Error(), nil)
		return
	}

	// 5. 判断是否编辑成功
	if !ok {
		app.NewResponse(c).JsonReturn(false, "编辑菜单失败", nil)
		return
	}

	app.NewResponse(c).JsonReturn(true, "编辑菜单成功", nil)
	return
}

// @title AdminRoleGetMenus
// @description 获取 当前 登陆用户角色 / 目标角色 分配的菜单
func AdminRoleGetMenus(c *gin.Context) {
	// 1. 当前 角色
	role, ok := checkAndGetCurrentRole(c)
	if !ok {
		app.NewResponse(c).JsonReturn(false, "对不起，获取当前用户角色失败!", nil)
		return
	}

	// 2. 当前角色分配的菜单
	menus, errMenus := partner_admin_menus.GetItemByRoleIdFromCache(role.Id)
	if errMenus != nil {
		app.NewResponse(c).JsonReturn(false, errMenus.Error(), nil)
		return
	}

	currentMenusTree := partner_admin_menus.BuildMenuCheckDataTree(menus, 0, 2)

	// 3. 目标角色
	targetRole, errTar := getAdminRoleFromParams(c)
	if errTar != nil {
		app.NewResponse(c).JsonReturn(false, errTar.Error(), nil)
		return
	}

	// 4. 目标角色分配的菜单
	targetMenus, errTaeMenus := partner_admin_menus.GetItemByRoleIdFromCache(targetRole.Id)
	if errTaeMenus != nil {
		app.NewResponse(c).JsonReturn(false, errTaeMenus.Error(), nil)
		return
	}

	// 5. 获取目标角色的menuId 作为选中的id
	defaultCheckedMenus := make([]int64, 0)
	for cid, _ := range targetMenus {
		defaultCheckedMenus = append(defaultCheckedMenus, cid)
	}

	returnData := make(map[string]interface{})
	returnData["checked_menus"] = defaultCheckedMenus
	returnData["current_menus"] = currentMenusTree

	app.NewResponse(c).JsonReturn(true, "获取数据成功", returnData)
	return
}

// @title AdminRoleGetPermissions
// @description 获取 当前 登陆用户角色 / 目标角色 分配的权限
func AdminRoleGetPermissions(c *gin.Context) {
	// 1. 当前 角色
	role, ok := checkAndGetCurrentRole(c)
	if !ok {
		app.NewResponse(c).JsonReturn(false, "对不起，获取当前用户角色失败!", nil)
		return
	}

	// 2. 但前角色 分配的权限
	parentPermissions, err := role.Permissions()
	if err != nil || role == nil {
		app.NewResponse(c).JsonReturn(false, "对不起，后去当前用户权限失败!", nil)
	}

	for i, item := range parentPermissions {
		fmt.Println(i, item.Name)
	}
	currentMenusTree := admin_permissions.BuildPermissionTree(parentPermissions, 0)

	// 3. 目标角色
	targetRole, errTar := getAdminRoleFromParams(c)
	if errTar != nil {
		app.NewResponse(c).JsonReturn(false, errTar.Error(), nil)
		return
	}

	// 4. 目标角色 拥有的权限ID
	targetPermissions, errTarget := targetRole.HelpPermissionToKey()
	if errTarget != nil || role == nil {
		app.NewResponse(c).JsonReturn(false, "对不起，后去当前用户权限失败!", nil)
		return
	}

	returnData := make(map[string]interface{})
	returnData["current_permissions"] = currentMenusTree
	returnData["checked_permissions"] = targetPermissions

	app.NewResponse(c).JsonReturn(true, "获取数据成功", returnData)
	return
}

// @title AdminRoleEditPermissions
// @description 编辑角色权限
func AdminRoleEditPermissions(c *gin.Context) {
	// 1. 获取当前角色
	currentRole, ok := checkAndGetCurrentRole(c)
	if !ok {
		app.NewResponse(c).JsonReturn(false, "对不起, 无效的登陆管理员", nil)
		return
	}

	// 2. 获取当前目标角色
	targetRole, errTar := getAdminRoleFromParams(c)
	if errTar != nil {
		app.NewResponse(c).JsonReturn(false, errTar.Error(), nil)
		return
	}

	// ３. 获取传递的参数 menu ids 并转成map[int64]int64
	checkedPermissionStrMapIds := c.PostFormMap("data")
	checkedPermissionInt64MapIds, errTrans := cmap.StringMapToInt64Map(checkedPermissionStrMapIds)
	if errTrans != nil {
		app.NewResponse(c).JsonReturn(false, errTrans.Error(), nil)
		return
	}

	// 4. 编辑
	ok, errEdit := currentRole.EditRolePermissions(targetRole, checkedPermissionInt64MapIds)
	if errEdit != nil {
		app.NewResponse(c).JsonReturn(false, errEdit.Error(), nil)
		return
	}

	// 5. 判断是否编辑成功
	if !ok {
		app.NewResponse(c).JsonReturn(false, "编辑菜单失败", nil)
		return
	}

	app.NewResponse(c).JsonReturn(true, "编辑菜单成功", nil)
	return
}

// 添加角色
func AdminRoleAdd(c *gin.Context) {

	// 编辑跳转到编辑逻辑
	id := c.PostForm("id")
	if id != "" {
		AdminRoleEdit(c)
		return
	}

	// 判定当前登陆用户是否存在
	currentAdminUser, errCurrent := admin_api.GetLoginAdminUser(c)
	if errCurrent != nil {
		app.NewResponse(c).JsonReturn(false, errCurrent.Error(), nil)
		return
	}

	// 获取当前角色
	role, err := currentAdminUser.Role()
	if err != nil || role == nil {
		app.NewResponse(c).JsonReturn(false, "对不起，当前用户角色不存在!", nil)
		return
	}

	var validaParams admin_roles.AdminRoleAddParams

	if err := c.ShouldBind(&validaParams); err != nil {
		app.NewResponse(c).JsonReturn(false, "bind-json-"+err.Error(), nil)
		return
	}

	// 添加IP
	validaParams.Ip = c.ClientIP()
	validaParams.UserId = currentAdminUser.Id

	adminUser, err := role.AddRole(validaParams)
	if err != nil {
		app.NewResponse(c).JsonReturn(false, err.Error(), adminUser)
		return
	}

	app.NewResponse(c).JsonReturn(true, "添加数据成功", adminUser)
	return
}

// @title AdminRoleEdit
// @description 编辑角色
func AdminRoleEdit(c *gin.Context) {
	// 教研
	targetRole, err := getAdminRoleFromParams(c)
	if err != nil {
		app.NewResponse(c).JsonReturn(false, err.Error(), nil)
		return
	}

	var validaParams admin_roles.AdminRoleAddParams

	if err := c.ShouldBind(&validaParams); err != nil {
		app.NewResponse(c).JsonReturn(false, "bind-json-"+err.Error(), nil)
		return
	}

	ok, err := targetRole.EditRoleInfo(validaParams)
	if err != nil {
		app.NewResponse(c).JsonReturn(false, err.Error(), nil)
		return
	}

	if !ok {
		app.NewResponse(c).JsonReturn(false, "更新失败!", nil)
		return
	}

	app.NewResponse(c).JsonReturn(true, "添加数据成功", nil)
	return
}

// 修改状态
func AdminRoleStatus(c *gin.Context) {
	targetRole, err := getAdminRoleFromParams(c)
	if err != nil {
		app.NewResponse(c).JsonReturn(false, err.Error(), nil)
		return
	}

	ok, errModify := targetRole.ModifyStatus()
	if errModify != nil {
		app.NewResponse(c).JsonReturn(false, errModify.Error(), nil)
		return
	}

	if !ok {
		app.NewResponse(c).JsonReturn(false, "对不起, 修改角色失败, 请联系客服", nil)
		return
	}

	app.NewResponse(c).JsonReturn(true, "恭喜, 修改角色状态成功", nil)
	return
}

/** ====================== validate ========================= **/
// 检测并返回 当前 角色
func checkAndGetCurrentRole(c *gin.Context) (*admin_roles.AdminRoles, bool) {
	// 判定当前登陆用户是否存在
	// 判定当前登陆用户是否存在
	currentAdminUser, errCurrent := admin_api.GetLoginAdminUser(c)
	if errCurrent != nil {
		return nil, false
	}

	role, err := currentAdminUser.Role()
	if err != nil {
		return nil, false
	}

	if role.Id == 0 {
		return nil, false
	}

	return role, true
}

// @title getAdminRoleFromParams
// @description 内置方法　通过参数id获取目标对象, 验证当前登陆用户是否可以操作目标角色
func getAdminRoleFromParams(c *gin.Context) (*admin_roles.AdminRoles, error) {
	id := c.PostForm("id")
	if id == "" {
		return nil, app.NewError("对不起, 角色ID不能为空")
	}

	int64Id, errConv := strconv.ParseInt(id, 10, 64)
	if errConv != nil {
		return nil, app.NewError("对不起, 角色ID格式不正确")
	}

	// 目标角色
	role, errRole := admin_roles.GetItemFromCacheById(int64Id)
	if errRole != nil {
		return nil, app.NewError("对不起, 目标角色不存在")
	}

	// 判定当前登陆用户是否存在
	// 判定当前登陆用户是否存在
	currentAdminUser := partner_api.GetLoginPartnerAdminUser(c)

	currentRole, errCurrent := currentAdminUser.Role()
	if errCurrent != nil {
		return nil, app.NewError(errCurrent)
	}

	// 是否上下级
	ok, errHas := currentRole.HasChildRole(int64Id)
	if errHas != nil {
		return nil, app.NewError(errHas)
	}

	if !ok {
		return nil, app.NewError("对不起, 您不具有修改目标角色的权限!")
	}

	return role, nil
}
